package com.cooldatasoft.taskManager.component;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.vaadin.kim.countdownclock.CountdownClock;

import com.cooldatasoft.domain.model.Project;
import com.cooldatasoft.domain.model.RolesEnum;
import com.cooldatasoft.domain.model.Task;
import com.cooldatasoft.domain.model.User;
import com.cooldatasoft.domain.service.TaskService;
import com.cooldatasoft.domain.service.UserProjectRolesService;
import com.cooldatasoft.security.TaskManagerSecurityManager;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptAll;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.ui.AbsoluteLayout;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.DragAndDropWrapper;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.DragAndDropWrapper.DragStartMode;
import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable;
import com.vaadin.ui.Window.Notification;

@SuppressWarnings("serial")
@Configurable(preConstruction = true)
public class ProjectProgressView extends CustomComponent {

	@AutoGenerated
	private AbsoluteLayout mainLayout;

	@AutoGenerated
	private VerticalLayout myProjectsVerticalLayout;

	@AutoGenerated
	private HorizontalLayout taskTablesHorizontalLayout;

	@AutoGenerated
	private HorizontalLayout headersLayout;

	@AutoGenerated
	private HorizontalLayout topLayout;

	@AutoGenerated
	private CountdownClock cc;
	
	@AutoGenerated
	private Label done_label;
	@AutoGenerated
	private Label inProgress_label;
	@AutoGenerated
	private Label toDo_label;
	
	@Autowired
	private UserProjectRolesService userProjectRolesService;
	
	@Autowired
	private TaskManagerSecurityManager taskManagerSecurityManager;
	
	@Autowired
	private TaskService taskService;
	
	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	private VerticalLayout vlProgress;
	private VerticalLayout vlDone;
	private GridLayout gridLayoutToDo;
	private GridLayout gridLayoutProgress;
	private GridLayout gridLayoutProgressMy;
	private GridLayout gridLayoutDoneMy;
	private GridLayout gridLayoutDone;
	
	private DragAndDropWrapper layoutWrapperInProgress;
	private DragAndDropWrapper layoutWrapperDone;
	private DragAndDropWrapper layoutWrapperToDo;
	
	private Project myCurrentProject;
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public ProjectProgressView(Project currentProject) {
		myCurrentProject = currentProject;
		buildMainLayout();
		setCompositionRoot(mainLayout);
		
		inicializeVerticalLayouts();
		inicializeMyProjectsTabSheet();
		loadProject();
	}
	
	private void inicializeVerticalLayouts(){
		vlProgress = new VerticalLayout();
		vlProgress.setSpacing(true);
		vlProgress.setWidth("100%");
		vlProgress.setHeight("100%");
		
		vlDone = new VerticalLayout();
		vlDone.setSpacing(true);
		vlDone.setHeight("100%");
		vlDone.setWidth("100%");
	}
	
	private void setCountDown() {	
		Calendar cal = Calendar.getInstance();
		cal.setTime(myCurrentProject.getFinished());
		
		cc.setDate(cal.getTime());
		cc.setFormat("<span style='font: bold 13px Arial; margin: 10px'>Countdown to project end:</span><span> %dd, %hh:%mmin:%ssec</span>");
	}
	
	private void refreshTasksGridLayout(Project project, GridLayout gridLayout,String taskStatus){
		gridLayout.removeAllComponents();
		List<Task> tasks = new ArrayList<Task>();		
		tasks = taskService.getTasksByTaskStatusOnProject(taskStatus, project);
		if(tasks !=null){
			for (final Task task : tasks) {
				
				Label taskName = new Label(task.getTaskName());
				NativeButton taskDescription = new NativeButton();
				taskDescription.setStyleName("taskIconSmall");
				taskDescription.addListener(new Button.ClickListener() {
					
					@Override
					public void buttonClick(com.vaadin.ui.Button.ClickEvent event) {
						getWindow().showNotification(TaskManagerNotification.showTaskNotification("Task information", task));
						
					}
				});
				
				VerticalLayout vl = new VerticalLayout();
				vl.addComponent(taskDescription);
				vl.addComponent(taskName);
				
				final DragAndDropWrapper vlWrap = new DragAndDropWrapper(vl);
				vlWrap.setDescription(String.valueOf(task.getIdTask()));
				vlWrap.setDragStartMode(DragStartMode.WRAPPER);
				vlWrap.setStyleName("boldText");
				User user1 = task.getUser();
				if(user1 !=null){
					if(user1.getIdUser() == taskManagerSecurityManager.getCurrentUser().getIdUser()){
						vlWrap.setSizeUndefined();
						gridLayout.addComponent(vlWrap);
					}else{
						
					}
				}else{
					vlWrap.setSizeUndefined();
					gridLayoutToDo.addComponent(vlWrap);
				}
				
				// Set the wrapper to wrap tightly around the component
				
			}
		}
	}
	
	private void loadProject() {
		gridLayoutToDo.removeAllComponents();
		gridLayoutDoneMy.removeAllComponents();
		gridLayoutProgress.removeAllComponents();
		gridLayoutProgressMy.removeAllComponents();
		gridLayoutDoneMy.removeAllComponents();
		
		if(myCurrentProject != null){
			List<Task> tasks = taskService.getTasksToProject(myCurrentProject);
			if(tasks != null){
				for (final Task task : tasks) {
					Label taskName = new Label(task.getTaskName());
					NativeButton taskDescription = new NativeButton();
					taskDescription.setStyleName("taskIconSmall");
					taskDescription.addListener(new Button.ClickListener() {
						
						@Override
						public void buttonClick(com.vaadin.ui.Button.ClickEvent event) {
							getWindow().showNotification(TaskManagerNotification.showTaskNotification("Task information", task));
							
						}
					});
							
					VerticalLayout vl = new VerticalLayout();
					vl.addComponent(taskDescription);
					vl.addComponent(taskName);
					
					final DragAndDropWrapper vlWrap = new DragAndDropWrapper(vl);
					vlWrap.setDescription(String.valueOf(task.getIdTask()));
					vlWrap.setDragStartMode(DragStartMode.WRAPPER);
					vlWrap.setStyleName("boldText");
					
					// Set the wrapper to wrap tightly around the component
					vlWrap.setSizeUndefined();
					
					User user = task.getUser();
					if(user !=null){
						if(task.getUser().getIdUser() != taskManagerSecurityManager.getCurrentUser().getIdUser()){
							vlWrap.setDragStartMode(DragStartMode.NONE);
						}
					}
					
					if (task.getTaskStatus().equals("to do")) {
						gridLayoutToDo.addComponent(vlWrap);
					} else if (task.getTaskStatus().equals("in progress")) {
						if(task.getUser().getIdUser() == taskManagerSecurityManager.getCurrentUser().getIdUser()){
							gridLayoutProgressMy.addComponent(vlWrap);
						}else{
							gridLayoutProgress.addComponent(vlWrap);
						}
					} else {
						if(task.getUser().getIdUser() == taskManagerSecurityManager.getCurrentUser().getIdUser()){
							gridLayoutDoneMy.addComponent(vlWrap);
						}else{
							gridLayoutDone.addComponent(vlWrap);
						}
					}
				}
			}else{
				//getWindow().showNotification("Project has any tasks", Notification.TYPE_ERROR_MESSAGE);
			}
			setCountDown();
		}
	}
	
	@AutoGenerated
	private AbsoluteLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new AbsoluteLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(false);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// myProjectsVerticalLayout
		myProjectsVerticalLayout = buildMyProjectsVerticalLayout();
		mainLayout.addComponent(myProjectsVerticalLayout,
				"top:0.0px;left:0.0px;");
		
		return mainLayout;
	}

	@AutoGenerated
	private VerticalLayout buildMyProjectsVerticalLayout() {
		// common part: create layout
		myProjectsVerticalLayout = new VerticalLayout();
		myProjectsVerticalLayout.setImmediate(false);
		myProjectsVerticalLayout.setWidth("100.0%");
		myProjectsVerticalLayout.setHeight("100.0%");
		myProjectsVerticalLayout.setMargin(false);
		
		// topLayout
		topLayout = buildTopLayout();
		myProjectsVerticalLayout.addComponent(topLayout);
		
		// headersLayout
		headersLayout = buildHeadersLayout();
		myProjectsVerticalLayout.addComponent(headersLayout);
		
		// taskTablesHorizontalLayout
		taskTablesHorizontalLayout = new HorizontalLayout();
		taskTablesHorizontalLayout.setImmediate(false);
		taskTablesHorizontalLayout.setWidth("100.0%");
		taskTablesHorizontalLayout.setHeight("100.0%");
		taskTablesHorizontalLayout.setMargin(false);
		taskTablesHorizontalLayout.setSpacing(true);
		myProjectsVerticalLayout.addComponent(taskTablesHorizontalLayout);
		myProjectsVerticalLayout.setExpandRatio(taskTablesHorizontalLayout,
				1.0f);
		
		return myProjectsVerticalLayout;
	}
	
	@AutoGenerated
	private HorizontalLayout buildHeadersLayout() {
		// common part: create layout
		headersLayout = new HorizontalLayout();
		headersLayout.setImmediate(false);
		headersLayout.setWidth("100.0%");
		headersLayout.setHeight("35px");
		headersLayout.setMargin(false);
		
		// toDo_label
		toDo_label = new Label();
		toDo_label.setStyleName("taskHeader");
		toDo_label.setImmediate(false);
		toDo_label.setWidth("100.0%");
		toDo_label.setHeight("-1px");
		toDo_label.setValue("ToDo tasks");
		headersLayout.addComponent(toDo_label);
		headersLayout.setExpandRatio(toDo_label, 1.0f);
		
		// inProgress_label
		inProgress_label = new Label();
		inProgress_label.setStyleName("taskHeader inProgMarg");
		inProgress_label.setImmediate(false);
		inProgress_label.setWidth("100.0%");
		inProgress_label.setHeight("-1px");
		inProgress_label.setValue("In-Progress tasks");
		headersLayout.addComponent(inProgress_label);
		headersLayout.setExpandRatio(inProgress_label, 1.0f);
		
		// done_label
		done_label = new Label();
		done_label.setStyleName("taskHeader");
		done_label.setImmediate(false);
		done_label.setWidth("100.0%");
		done_label.setHeight("-1px");
		done_label.setValue("Done tasks");
		headersLayout.addComponent(done_label);
		headersLayout.setExpandRatio(done_label, 1.0f);
		
		return headersLayout;
	}
	
	@AutoGenerated
	private HorizontalLayout buildTopLayout() {
		// common part: create layout
		topLayout = new HorizontalLayout();
		topLayout.setImmediate(false);
		topLayout.setWidth("100.0%");
		topLayout.setHeight("-1px");
		topLayout.setMargin(false);
		
		// cc
		cc = new CountdownClock();
		cc.setImmediate(false);
		cc.setWidth("100.0%");
		cc.setHeight("100.0%");
		topLayout.addComponent(cc);
		topLayout.setComponentAlignment(cc, new Alignment(34));
		
		return topLayout;
	}
	
	private void inicializeMyProjectsTabSheet(){
		gridLayoutToDo = new GridLayout();
		gridLayoutToDo.setColumns(3);
		gridLayoutToDo.setRows(6);
		gridLayoutToDo.setMargin(true);
		gridLayoutToDo.setSpacing(true);
		gridLayoutToDo.setStyleName("toDoLayout");
		gridLayoutToDo.setHeight("96%");
		gridLayoutToDo.setWidth("96%");
		
		gridLayoutProgressMy = new GridLayout();
		gridLayoutProgressMy.setColumns(3);
		gridLayoutProgressMy.setRows(6);
		gridLayoutProgressMy.setMargin(true);
		gridLayoutProgressMy.setSpacing(true);
		gridLayoutProgressMy.setStyleName("inProgMyLayout");
		gridLayoutProgressMy.setHeight("96%");
		gridLayoutProgressMy.setWidth("96%");
		
		gridLayoutProgress = new GridLayout();
		gridLayoutProgress.setColumns(3);
		gridLayoutProgress.setRows(6);
		gridLayoutProgress.setMargin(true);
		gridLayoutProgress.setSpacing(true);
		gridLayoutProgress.setStyleName("inProgLayout");
		gridLayoutProgress.setHeight("96%");
		gridLayoutProgress.setWidth("97%");
		
		gridLayoutDoneMy= new GridLayout();
		gridLayoutDoneMy.setColumns(3);
		gridLayoutDoneMy.setRows(6);
		gridLayoutDoneMy.setMargin(true);
		gridLayoutDoneMy.setSpacing(true);
		gridLayoutDoneMy.setStyleName("doneMyLayout");
		gridLayoutDoneMy.setHeight("96%");
		gridLayoutDoneMy.setWidth("96%");
		
		gridLayoutDone= new GridLayout();
		gridLayoutDone.setColumns(3);
		gridLayoutDone.setRows(6);
		gridLayoutDone.setMargin(true);
		gridLayoutDone.setSpacing(true);
		gridLayoutDone.setStyleName("doneLayout");
		gridLayoutDone.setHeight("96%");
		gridLayoutDone.setWidth("97%");
		
		layoutWrapperInProgress = new DragAndDropWrapper(gridLayoutProgressMy);
		layoutWrapperInProgress.setHeight("99%");	
		layoutWrapperDone = new DragAndDropWrapper(gridLayoutDoneMy);
		layoutWrapperDone.setHeight("99%");
		layoutWrapperToDo= new DragAndDropWrapper(gridLayoutToDo);
		layoutWrapperToDo.setHeight("100%");
		
		User currentUser = taskManagerSecurityManager.getCurrentUser();
		if (currentUser.getSystemRole() == RolesEnum.STUDENT) {
				
			layoutWrapperInProgress.setDropHandler(new DropHandler() {
				
				@Override
				public AcceptCriterion getAcceptCriterion() {
					return AcceptAll.get();
				}
				
				@Override
				public void drop(DragAndDropEvent event) {
					try{
						WrapperTransferable t =
						        (WrapperTransferable) event.getTransferable();
						
						gridLayoutProgressMy.addComponent(t.getSourceComponent());
						
						String idString = ((AbstractComponent)t.getSourceComponent()).getDescription();
						Long id = Long.valueOf(idString);	               
						
						Task task = taskService.getById(id);
		                task.setTaskStatus("in progress");
		                task.setUser(taskManagerSecurityManager.getCurrentUser());
		                taskService.updateTask(task);
		                
		                refreshTasksGridLayout(myCurrentProject, gridLayoutToDo,"to do");
						refreshTasksGridLayout(myCurrentProject, gridLayoutProgressMy, "in progress");
						
					}catch(IllegalArgumentException ex){
						getWindow().showNotification("Component is already in containter", Notification.TYPE_ERROR_MESSAGE);
					}
						
				}
			});
			
			layoutWrapperDone.setDropHandler(new DropHandler() {
				
				@Override
				public AcceptCriterion getAcceptCriterion() {
					return AcceptAll.get();
				}
				
				@Override
				public void drop(DragAndDropEvent event) {
					try{
						WrapperTransferable t =
						        (WrapperTransferable) event.getTransferable();
						
						String idString = ((AbstractComponent)t.getSourceComponent()).getDescription();
						Long id = Long.valueOf(idString);
		                
						Task task = taskService.getById(id);
					
						if(task.getTaskStatus().equals("in progress")){
							gridLayoutDoneMy.addComponent(t.getSourceComponent());
							task.setTaskStatus("done");
		                	taskService.updateTask(task);
						}else{
							getWindow().showNotification("Task status must be in progress",Notification.TYPE_ERROR_MESSAGE);
						}
						refreshTasksGridLayout(myCurrentProject, gridLayoutDoneMy ,"done");
						refreshTasksGridLayout(myCurrentProject, gridLayoutProgressMy, "in progress");
					}catch(IllegalArgumentException ex){
						getWindow().showNotification("Component is already in containter", Notification.TYPE_ERROR_MESSAGE);
					}
					
				}
			});
			
			layoutWrapperToDo.setDropHandler(new DropHandler() {
				
				@Override
				public AcceptCriterion getAcceptCriterion() {
					return AcceptAll.get();
				}
				
				@Override
				public void drop(DragAndDropEvent event) {
					try{
						WrapperTransferable t =
						        (WrapperTransferable) event.getTransferable();
						
						gridLayoutToDo.addComponent(t.getSourceComponent());
						
						String idString = ((AbstractComponent)t.getSourceComponent()).getDescription();
						Long id = Long.valueOf(idString);
		                
						Task task = taskService.getById(id);
						task.setTaskStatus("to do");
						task.setUser(null);
						taskService.updateTask(task);

						refreshTasksGridLayout(myCurrentProject, gridLayoutToDo,"to do");
						refreshTasksGridLayout(myCurrentProject, gridLayoutProgressMy, "in progress");

					}catch(IllegalArgumentException ex){
						getWindow().showNotification("Component is already in containter", Notification.TYPE_ERROR_MESSAGE);
					}
				}
			});
		}
		
		Label myTasks = new Label("My tasks");
		vlProgress.addComponent(myTasks);
		vlProgress.addComponent(layoutWrapperInProgress);
		Label otherTasks = new Label("Other tasks");
		vlProgress.addComponent(otherTasks);
		vlProgress.addComponent(gridLayoutProgress);
		vlProgress.setExpandRatio(myTasks, 0.0f);
		vlProgress.setExpandRatio(otherTasks, 0.0f);
		vlProgress.setExpandRatio(layoutWrapperInProgress, 1.0f);
		vlProgress.setExpandRatio(gridLayoutProgress, 1.0f);
		
		Label myTasksdone = new Label("My tasks");
		vlDone.addComponent(myTasksdone);
		vlDone.addComponent(layoutWrapperDone);
		Label otherTasksDone = new Label("Other tasks");
		vlDone.addComponent(otherTasksDone);
		vlDone.addComponent(gridLayoutDone);
		vlDone.setExpandRatio(myTasksdone, 0.0f);
		vlDone.setExpandRatio(otherTasksDone, 0.0f);
		vlDone.setExpandRatio(layoutWrapperDone, 1.0f);
		vlDone.setExpandRatio(gridLayoutDone, 1.0f);
		
		taskTablesHorizontalLayout.addComponent(layoutWrapperToDo);
		taskTablesHorizontalLayout.addComponent(vlProgress);
		taskTablesHorizontalLayout.addComponent(vlDone);
	}
	
}
